package rp.lee.weblog;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpHeaders.Names;
import io.netty.handler.codec.http.HttpHeaders.Values;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.InterfaceHttpData.HttpDataType;
import io.netty.util.CharsetUtil;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonElement;

/**
 * 
 * title: HttpServerInboundHandler.java 
 * http请求响应处理
 *
 * @author rplees
 * @email rplees.i.ly@gmail.com
 * @version 1.0  
 * @created Mar 31, 2017 10:34:43 AM
 */
public class HttpServerInboundHandler extends ChannelInboundHandlerAdapter {
	private Logger logger = LoggerFactory.getLogger(HttpServerInboundHandler.class);

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		if (msg instanceof HttpRequest) {
			HttpRequest request = (HttpRequest) msg;
			String path = path(request.getUri());
			if("favicon.ico".equals(path)) {//忽略
				return;
			}
			
			Map<String, String> parameters = parameters(request);
			logger.info("{} 参数列表:", path);
			for(Entry<String, String> entry : parameters.entrySet()) {
				logger.info("	{} = {}", entry.getKey(), entry.getValue());
			}
			
			InputStream inputStream = this.getClass().getResourceAsStream("log.html");
			String html = IOUtils.toString(inputStream);
			
			FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(html.toString().getBytes("UTF-8")));
			response.headers().set(Names.CONTENT_TYPE, "text/html");
			response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
			if (HttpHeaders.isKeepAlive(request)) {
				response.headers().set(Names.CONNECTION, Values.KEEP_ALIVE);
			}
			
			ctx.write(response);
			ctx.flush();
		}
	}
	
	public void httpJsonReponse(JsonElement je, ChannelHandlerContext ctx, HttpRequest request) throws UnsupportedEncodingException {
		FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(je.toString().getBytes("UTF-8")));
		response.headers().set(Names.CONTENT_TYPE, "application/*+json");
		response.headers().set(Names.CONTENT_LENGTH, response.content().readableBytes());
		if (HttpHeaders.isKeepAlive(request)) {
			response.headers().set(Names.CONNECTION, Values.KEEP_ALIVE);
		}
		ctx.write(response);
		ctx.flush();
	}
	
	public Map<String, String> parameters(HttpRequest request) {
		Map<String, String> parameters = new HashMap<String, String>();
		if (HttpMethod.GET == request.getMethod()) {
			// 是GET请求
			QueryStringDecoder decoder = new QueryStringDecoder(request.getUri(), Charset.forName("UTF-8"), true);
			for (Entry<String, List<String>> entry : decoder.parameters().entrySet()) {
				parameters.put(entry.getKey(), entry.getValue().get(0));
			}
		} else if (HttpMethod.POST == request.getMethod()) {
			if(request instanceof HttpContent) {
				HttpContent httpContent = (HttpContent) request;
				ByteBuf content = httpContent.content();
				final StringBuilder buf = new StringBuilder();
				buf.append(content.toString(CharsetUtil.UTF_8));
			}
		
			// 是POST请求
			HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), request);
			for (InterfaceHttpData parm : decoder.getBodyHttpDatas()) {
				if (parm.getHttpDataType() == HttpDataType.Attribute) {
					Attribute data = (Attribute) parm;
					try {
						parameters.put(data.getName(), data.getValue());
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				
			}
		}
		
		return parameters;
	} 
	
	
	 /**
     * Returns the decoded path string of the URI.
     * 
     * /bill_order?o=1  ==> bill_order
     * /bill_order		==>	bill_order
     */
    public String path(String uri) {
        int pathEndPos = uri.indexOf('?');
        if (pathEndPos < 0) {
            return uri.substring(1);
        } else {
            return uri.substring(1, pathEndPos);
        }
    }
    
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		ctx.flush();
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		logger.error("message:{}-localizedMessage{}", cause.getMessage(), cause.getLocalizedMessage());
		ctx.close();
	}
}